using System;
using System.Net.Sockets;

/*	-----------------------------------------------------------------------	
	Copyright:	umlungu consulting (pty) ltd
	Author:		Alan Benington
	Started:	2007-10-27
	Status:		beta
	Version:	2.0.0
	Build:		20071027
	License:	GNU General Public License
	-----------------------------------------------------------------------	*/

/*	-----------------------------------------------------------------------	
	Development Notes:
	==================
	20071027:	Start of .Net2 version from EmailX.1.0.2
	-----------------------------------------------------------------------	*/

namespace umlungu.engineX.emailX {
	/// <summary>
	/// The x_tcpcom class does basic sockets communication.
	/// <para>Additional information about the class</para>
	/// </summary>
	public class x_tcpcom {

		#region Invisible properties
		private x_exception x_excep;
		private TcpClient comClient;
		private NetworkStream comStream;
		#endregion

		#region Visible properties
		private string server;
		/// <summary>Name of the Server</summary>
		/// <value>The server domain name or ip address</value>
		public string Server {
			get {	return server;	}
			set {	server = value;	}
		}
		private int port;
		/// <summary>The port number</summary>
		/// <value>The number of the tcp port for connection</value>
		public int Port {
			get {	return port;	}
			set {	port = value;	}
		}
		private string error = "No Error";
		/// <summary>Message when error</summary>
		/// <value>The error message, else "No Error"</value>
		public string Error {
			get {	return error;	}
			set {	error = value;	}
		}
		/// <summary>Indicates whether data is available.</summary>
		/// <value>true if data is available</value>
		public bool DataWaiting {
			get {	return comStream.DataAvailable;	}
		}
		/// <summary>The exception when an error encountered.</summary>
		/// <value>the x_exception of the error</value>
		public x_exception GetError{
			get {	return x_excep;	}
		}
		#endregion

		#region Constructors/Destructors
		/// <overloads>Constructor</overloads>
		/// <summary>Default constructor</summary>
		public x_tcpcom() {
			initialise();
		}
		/// <summary>Set default server and port</summary>
		/// <param name="ServerName">The server to connect to</param>
		/// <param name="PortNumber">The port on the server for the connection</param>
		public x_tcpcom(string ServerName, int PortNumber) {
			Port = PortNumber;
			Server = ServerName;
			initialise();
		}
		#endregion

		#region Public methods
		/// <overloads>Establish a connection with the server</overloads>
		/// <summary>
		/// Specify the Server and Port
		/// </summary>
		/// <param name="ServerName">The server to connect to</param>
		/// <param name="PortNumber">The port on the server for the connection</param>
		public bool Connect(string ServerName, int PortNumber) {
			Port = PortNumber;
			Server = ServerName;
			return Connect();
		}
		/// <summary>
		/// Connect on default Server and Port
		/// </summary>
		public bool Connect() {
			try {
				comClient.Connect(Server, Port);
				comStream = comClient.GetStream();
				return true;
			} catch(System.Exception e) {
				x_excep = new x_exception("error_connect", String.Concat("Connect Error: ", e.Message));
				return false;
			}
		}
		/// <summary>
		/// Read data from open connection
		/// </summary>
		public string ReadData() {
			try {
				// init vars
				string Data = null;
				byte[] RawData;
				System.Text.ASCIIEncoding Encoder = new System.Text.ASCIIEncoding();

				// Clear previous errors
				this.ClearError();

				// check for able to read
				if (comStream.CanRead == false)
					throw (new Exception("Can't read from network stream, is the connection open?"));

				//Check for data
				if (comStream.DataAvailable == false)
					return null; //Not an error.. just nothing to get

				//Get Everything
				RawData = new byte[comClient.ReceiveBufferSize];
				comStream.Read(RawData, 0, RawData.Length);
                
				//Convert to string
				Data = Encoder.GetString(RawData);

				return Data;
			} catch(System.Exception e) {
				x_excep = new x_exception("error_read", String.Concat("Read Error: ", e.Message));
				return null;
			}

		}
		/// <summary>
		/// Send data to the open connection
		/// </summary>
		public bool SendData(string Data) {
			try {
				// init Vars
				System.Text.ASCIIEncoding Encoder = new System.Text.ASCIIEncoding();
				byte[] RawData = new byte[Data.Length];

				// Check for able to write
				if (comStream.CanWrite == false)
					throw new x_exception( "error_", "Can't write to network stream, is the connection open?");

				// Convert to byte[]
				RawData = Encoder.GetBytes(Data);

				// Send Everything
				comStream.Write(RawData,0,RawData.GetLength(0));

				return true;
			} catch (System.Exception e) {
				x_excep = new x_exception("error_send", String.Concat("Send Error: ", e.Message));
				return false;
			}

		}
		/// <summary>
		/// Disconnect from current server
		/// </summary>
		public bool Disconnect() {
			try {
				comClient.Close();
				return true;
			} catch(System.Exception e) {
				x_excep = new x_exception("error_disconnect", String.Concat("Disconnect Error: ", e.Message));
				return false;
			}
		}
		/// <summary>
		/// Reset the error condition
		/// </summary>
		public void ClearError() {
			x_excep = new x_exception("0", error);
		}
		#endregion
		
		#region Protected methods
		#endregion
				
		#region Private methods
		private void initialise() {
			x_excep = new x_exception("0", error);
			comClient = new TcpClient();
		}
		#endregion

	}
}
